# -*- coding=utf-8 -*-
# Author: Slp
# @Date : 2021-09-14

import json
import random
import re
import unittest

from src.common import log
from src.common.dingding import send_ding
from src.common.envconfig import envConfig
from src.common.newreadExcel import ReadExcel
from src.common.ddtNew import data, unpack, ddt

from src.common.get_method import OperatorCommon


@ddt
class CwtShopTest(unittest.TestCase, unittest.SkipTest):

    # setUPClass作用：在类中所有方法运行之前执行，只运行一次
    @classmethod
    def setUpClass(cls) -> None:
        cls.token = ''  # 小程序登录需要的token
        cls.orderId = ''  # 创建销售单的订单ID
        cls.mobile = '13058019302'
        cls.random_num = random.randint(100001, 999999)
        cls.num = int('18888' + str(cls.random_num))

    def activeVal(self, field_list, val):
        """
        用于替换接口中的变量的值
        :param field_list:
        :param val:
        :return:
        """
        if field_list:
            for s in field_list:
                if s == '#self.random_num#':
                    val = val.replace(s, str(self.random_num))
                elif s == '#self.token#':
                    val = val.replace(s, str(self.token))
                elif s == '#self.num#':
                    val = val.replace(s, str(self.num))
                elif s == '#self.orderId#':
                    val = val.replace(s, str(self.orderId))
            log.logger_info.info('激活后的值为：' + val)
            return val
        else:
            # 如果请求里面不存在变量，则直接返回输入的值
            log.logger_info.info('激活后的值为：' + val)
            return val

    @data(*ReadExcel().getExcel('cwt_shop'))
    @unpack
    def test_case(self, env, api_name, method_name, desc_name, url, is_skip, headers_name, body, expect_result):
        """

        :param env: 执行环境
        :param api_name: 接口名称
        :param method_name: 请求方式
        :param desc_name: 用例名称
        :param url: 接口路径
        :param is_skip: 是否跳过
        :param headers_name: 头部信息
        :param body: 请求body
        :param expect_result:预期结果
        :return:当前接口的执行情况
        """

        log.logger_info.info("-------开始" + api_name + "下的" + method_name + "接口用例执行---------")
        log.logger_info.info("当前获取到的URL：" + url + "当前获取到的body：" + body + "当前获取到的headers_name：" + headers_name +
                             "当前获取到的method_name：" + method_name)
        cookie = ''
        re_str = '#.*?#'  # 正则表达式：找出表格中对应的字段
        self._testProjectName = '商户小程序'  # 测试报告中展示
        self._testMethodDoc = desc_name  # 测试报告中展示
        self._testMethodName = api_name  # 测试报告中展示
        self._testMethodUrl = url  # 测试报告中展示

        # 判断当前用例是否跳过
        if str(is_skip).strip() == "是" or env in envConfig():
            self.skipTest('skip case')
            log.logger_info.info("当前模块：" + api_name, "下的：" + method_name, "，配置为跳过，已自动跳过该用例执行！")
            return False
        try:
            # 判断不是登录相关接口的时候自动带入缓存的cookie值
            if method_name == 'post' or method_name == 'put':
                # 对请求体的格式转化处理
                self.body = str(body).strip()  # 先把请求体转化为字符串格式，并去除开头和结尾的空格
                # 使用正则获取请求体中参数化的字段列表
                log.logger_info.info("改变前的请求体是：" + str(self.body))
                re_list_body = re.findall(re_str, self.body)
                log.logger_info.info('匹配后的请求体值为：' + str(re_list_body))
                # 对body中参数化的字段进行激活赋值
                self.body = self.activeVal(re_list_body, self.body)
                # 先对 body 做类型转换
                if self.body:
                    self.body = eval(self.body)
                    # 对请求体中文转 json 后加密失败做处理
                    self.body = json.dumps(self.body)
                    log.logger_info.info("最终的请求体是：" + str(self.body))
            elif method_name == 'get':
                self.body = body
            self.header = str(headers_name).strip()  # 先把请求头转化为字符串格式，并去除开头和结尾的空格
            re_list_header = re.findall(re_str, self.header)
            log.logger_info.info("匹配后的请求头值为："+str(re_list_header))
            self.header = self.activeVal(re_list_header, self.header)
            log.logger_info.info("最终的请求头是：" + str(self.header))
            co = OperatorCommon()
            self.res = co.requestApi(url, self.body, str(self.header), method_name, cookie)
            if self.res.content:
                log.logger_info.info("当前接口返回值是：" + str(self.res.json()))
                print("当前接口返回值是：" + str(self.res.json()))
            # 针对不是登录接口的断言
            if api_name != 'login':
                expect_result_dict = json.loads(expect_result)
                actual_list = []
                expect_list = []
                actual_list.append(self.res.json()["code"])
                actual_list.append(self.res.json()["msg"])
                expect_list.append(expect_result_dict['code'])
                expect_list.append(expect_result_dict['msg'])
                self.assertListEqual(actual_list, expect_list, msg='断言值有误,code或者msg值与预期不一致！')
            # 从登录接口中获取cookie信息
            if api_name == 'login' and method_name == 'post':
                log.logger_info.info("登录接口返回值：" + str(self.res.json()))
                print("登录接口返回值：" + str(self.res.json()))
                CwtShopTest.token = self.res.json()['data']['token']
                log.logger_info.info("获取到的token是：" + CwtShopTest.token)
            if api_name == 'add_sale_order' and method_name == 'post':
                CwtShopTest.orderId = self.res.json()['data']
                log.logger_info.info("获取到的销售单ID是：" + str(CwtShopTest.orderId))
        except Exception as ex:
            send_ding("【车位通商户小程序在】" +env + "环境的【" + desc_name + "】模块请求抛异常：" + str(ex) + "@" + self.mobile, self.mobile)
            log.logger_error.error("执行" + env + "环境的【" + desc_name + "】模块请求抛异常：" + str(ex))
            raise Exception(str(ex))

    def tearDown(self) -> None:
        pass


if __name__ == '__main__':
    unittest.main()
